#lang racket

(define (translate pos cx cy)
  (list (+ (car pos) cx) (+ (cadr pos) cy)))
(define (rotate pos theta)
  (let ((x (car pos))
        (y (cadr pos)))
    (list (- (* x (cos theta)) (* y (sin theta)))
          (+ (* x (sin theta)) (* y (cos theta))))))
(define (T* theta pos n)
  (let ((c (/ (- (expt 2 n) 1) 2)))
    (translate
     (rotate
      (translate pos (- c) (- c))
      theta)
     c c)))
(define T+90 (curry T*    (/ pi 2)))
(define T-90 (curry T* (- (/ pi 2))))

(define (H n)
  (cond ((= n 0)
         '())
        ((= n 1)
         '((0 0) (0 1) (1 1) (1 0)))
        (else
         (let ((H- (H (- n 1)))
               (c (expt 2 (- n 1))))
           `(,@(reverse
                (map (lambda (pos) (T-90 pos (- n 1))) H-))
             ,@ (map (lambda (pos) (translate pos 0 c))H-)
             ,@ (map (lambda (pos) (translate pos c c))H-)
             ,@(reverse
                (map (lambda (pos)
                       (translate
                        (T+90 pos (- n 1)) c 0))      H-)))))))

(map (curry map round) (H 5))

